
import java.math.BigDecimal;
import java.math.RoundingMode;

public class JuveSim1 {

    /**
     * cette methode permet de lire un entier et gere une exeption si l
     * utilisateur entre autre chose qu un entier
     *
     * @exception NumberFormatException
     * @param none
     * @return entier le nombre entier lu
     */
    public static int validerEntier() {
        int entier = 0;
        boolean verifier = false;
        do {
            try {
                entier = Clavier.lireInt();
                verifier = false;
            } catch (NumberFormatException nfe) {
                System.out.print("Vous devez entrer un nombre entier :");
                verifier = true;
            }
        } while (verifier == true);
        return entier;
    }

    public static void main(String[] params) {
        BigDecimal montantTotalDesRabais = new BigDecimal("0.00");
        BigDecimal revenuTotalSansTaxesAvecRabais = new BigDecimal("0.00");
        BigDecimal revenuTotalAvecTaxeSansRabais = new BigDecimal("0.00");
        BigDecimal rabaisTotaPour2JourEtPlus = new BigDecimal("0.00");
        BigDecimal rabaisTotalPour2Jour = new BigDecimal("0.00");
        BigDecimal rabaisTotalPour1Jour = new BigDecimal("0.00");
        BigDecimal totalDeTaxe = new BigDecimal("0.00");
        BigDecimal rabais15PourCent = new BigDecimal("0.00");
        BigDecimal rabais10PourCent = new BigDecimal("0.00");
        BigDecimal rabais5PourCent = new BigDecimal("0.00");
        int nbreDeRabais15PourCent = 0;
        int nbreDeRabais10PourCent = 0;
        int nbreDeRabais5PourCent = 0;
        int nbreDeRabais0PourCent = 0;
        int nombreDeFacture = 0;
        int nombreTotalDeParticipant = 0;

        final BigDecimal NOUVELLE_TAXE = new BigDecimal("0.15");
        final BigDecimal RABAIS_15POUR_CENT = new BigDecimal("0.15");
        final BigDecimal RABAIS_10POUR_CENT = new BigDecimal("0.1");
        final BigDecimal RABAIS_5POUR_CENT = new BigDecimal("0.05");
        final BigDecimal PRIX_DE_BASE = new BigDecimal("50.00");
        final BigDecimal RABAIS_POUR_NOMBRE_DE_PARTICIPANT = new BigDecimal("5.00");
        final BigDecimal RABAIS_2E_JOURNEE = new BigDecimal("5.00");
        final BigDecimal RABAIS_3E_JOURNEE = new BigDecimal("20.00");
        final int LIMITE_INFERIEURE_DE_PARTICIPANT = 0;
        final int CODE_ANNULATION_DE_FACTURE = 0;
        final int CODE_ANNULATION_DE_CLIENT = 0;
        final int LIMITE_INFERIEURE_DE_LA_DUREE_DU_SEJOUR = 0;
        final int LIMITE_INFERIEURE_POUR_TERMINAISON = -1;
        final int NUMERO_DE_CLIENT_MINIMUM = 1000;
        final int NUMERO_DE_CLIENT_MAXIMUM = 4999;
        final int LIMITE_INFERIEURE_POUR_RABAIS_NOMBRE_PARTICIPANT = 5;
        final int BORNE_SUPERIEUR_CLSSE1 = 1999;
        final int BORNE_INFERIEUR_CLSSE2 = 2000;
        final int BORNE_SUPERIEUR_CLSSE2 = 2999;
        final int BORNE_INFERIEUR_CLSSE3 = 3000;
        final int BORNE_SUPERIEUR_CLSSE3 = 3999;

        boolean operationTermine = false;

        System.out.println("Ce programme facture les forfaits vacance/plein air avec ou sans rabais selon le cas");
        System.out.println("et affiche un bilan des differentes executions A la fermeture du programme");
        System.out.println();

        int numeroDeClient = 0;
        do {
            int nombreDeParticipant = 0;
            int dureeDuSejour = 0;
            BigDecimal montantAvantTaxesEtRabais = new BigDecimal("0");
            BigDecimal montantAvecTaxeSansRabais;
            BigDecimal montantFinal;
            BigDecimal rabais;
            BigDecimal taxes;
            BigDecimal montantAvantTaxesMoinsRabais;

            // Validation du numero de client
            while (!operationTermine) {
                System.out.print("N°Client ou un nombre negatif pour terminer: ");
                numeroDeClient = validerEntier();
                if (numeroDeClient > LIMITE_INFERIEURE_POUR_TERMINAISON && numeroDeClient < NUMERO_DE_CLIENT_MINIMUM || numeroDeClient > NUMERO_DE_CLIENT_MAXIMUM) {
                    System.out.println("ERREUR!");
                } else {
                    operationTermine = true;
                }
            }

            operationTermine = false;
            if (numeroDeClient > LIMITE_INFERIEURE_POUR_TERMINAISON) {
                // Validation du nombre de participant
                while (!operationTermine) {
                    System.out.print("Nombre de participant: ");
                    nombreDeParticipant = validerEntier();

                    if (nombreDeParticipant < LIMITE_INFERIEURE_DE_PARTICIPANT) {
                        System.out.println("ERREUR!");
                    } else {
                        operationTermine = true;
                    }
                }

                operationTermine = false;
                if (nombreDeParticipant != CODE_ANNULATION_DE_CLIENT) {
                    // Validation de la duree du sejour
                    while (!operationTermine) {
                        System.out.print("Duree de l'activite: ");
                        dureeDuSejour = validerEntier();
                        if (dureeDuSejour < LIMITE_INFERIEURE_DE_LA_DUREE_DU_SEJOUR) {
                            System.out.println("ERREUR!");
                        } else {
                            operationTermine = true;
                        }
                    }

                    operationTermine = false;
                    if (dureeDuSejour == CODE_ANNULATION_DE_FACTURE) {
                        System.out.println(" FACTURE ANNULEE");
                    } else {
                        nombreDeFacture = nombreDeFacture + 1;
                        nombreTotalDeParticipant = nombreTotalDeParticipant + nombreDeParticipant;

                        final int participantsSansRabais = (LIMITE_INFERIEURE_POUR_RABAIS_NOMBRE_PARTICIPANT - 1);
                        final int participantsAvecRabais = nombreDeParticipant - participantsSansRabais;

                        // Ajout du prix pour plus de 2 jours
                        int dureeDuSejourPourCalcul = dureeDuSejour;
                        if (dureeDuSejourPourCalcul > 2) {
                            montantAvantTaxesEtRabais = PRIX_DE_BASE.subtract(RABAIS_3E_JOURNEE).multiply(new BigDecimal(nombreDeParticipant));
                            montantAvantTaxesEtRabais = montantAvantTaxesEtRabais.multiply(new BigDecimal(dureeDuSejour - 2));
                            dureeDuSejourPourCalcul = 2;
                        }

                        switch (dureeDuSejourPourCalcul) {
                            case 2:
                                // Ajout du prix pour la 2e journee
                                if (nombreDeParticipant < LIMITE_INFERIEURE_POUR_RABAIS_NOMBRE_PARTICIPANT) {
                                    montantAvantTaxesEtRabais = montantAvantTaxesEtRabais.add(PRIX_DE_BASE.subtract(RABAIS_2E_JOURNEE).multiply(new BigDecimal(nombreDeParticipant)));
                                } else {
                                    BigDecimal montantSansRabais = PRIX_DE_BASE.subtract(RABAIS_2E_JOURNEE).multiply(new BigDecimal(participantsSansRabais));
                                    BigDecimal montantAvecRabais = PRIX_DE_BASE.subtract(RABAIS_2E_JOURNEE).subtract(RABAIS_POUR_NOMBRE_DE_PARTICIPANT);
                                    montantAvecRabais = montantAvecRabais.multiply(new BigDecimal(participantsAvecRabais));
                                    montantAvantTaxesEtRabais = montantAvantTaxesEtRabais.add(montantSansRabais).add(montantAvecRabais);
                                }
                            case 1:
                                // Ajout du prix pour la premiere journee
                                if (nombreDeParticipant < LIMITE_INFERIEURE_POUR_RABAIS_NOMBRE_PARTICIPANT) {
                                    montantAvantTaxesEtRabais = montantAvantTaxesEtRabais.add(PRIX_DE_BASE.multiply(new BigDecimal(nombreDeParticipant)));
                                } else {
                                    BigDecimal montantSansRabais = PRIX_DE_BASE.multiply(new BigDecimal(participantsSansRabais));
                                    BigDecimal montantAvecRabais = PRIX_DE_BASE.subtract(RABAIS_POUR_NOMBRE_DE_PARTICIPANT);
                                    montantAvecRabais = montantAvecRabais.multiply(new BigDecimal(participantsAvecRabais));
                                    montantAvantTaxesEtRabais = montantAvantTaxesEtRabais.add(montantSansRabais).add(montantAvecRabais);
                                }
                                break;
                            default:
                                System.err.println("Duree du sejour mal validee");
                                break;
                        }

                        // Calcul du rabais selon le numero de client
                        if (numeroDeClient >= NUMERO_DE_CLIENT_MINIMUM && numeroDeClient <= BORNE_SUPERIEUR_CLSSE1) {
                            rabais = montantAvantTaxesEtRabais.multiply(RABAIS_15POUR_CENT).setScale(2, RoundingMode.HALF_UP);
                            rabais15PourCent = rabais15PourCent.add(rabais).setScale(2, RoundingMode.HALF_UP);
                            nbreDeRabais15PourCent = nbreDeRabais15PourCent + 1;
                        } else if (numeroDeClient >= BORNE_INFERIEUR_CLSSE2 && numeroDeClient <= BORNE_SUPERIEUR_CLSSE2) {
                            rabais = montantAvantTaxesEtRabais.multiply(RABAIS_10POUR_CENT).setScale(2, RoundingMode.HALF_UP);
                            rabais10PourCent = rabais10PourCent.add(rabais).setScale(2, RoundingMode.HALF_UP);
                            nbreDeRabais10PourCent = nbreDeRabais10PourCent + 1;
                        } else if (numeroDeClient >= BORNE_INFERIEUR_CLSSE3 && numeroDeClient <= BORNE_SUPERIEUR_CLSSE3) {
                            rabais = montantAvantTaxesEtRabais.multiply(RABAIS_5POUR_CENT).setScale(2, RoundingMode.HALF_UP);
                            rabais5PourCent = rabais5PourCent.add(rabais).setScale(2, RoundingMode.HALF_UP);
                            nbreDeRabais5PourCent = nbreDeRabais5PourCent + 1;
                        } else {
                            rabais = new BigDecimal("0.00");
                            nbreDeRabais0PourCent = nbreDeRabais0PourCent + 1;
                        }

                        // Calcul des statistiques selon la duree du sejour
                        if (dureeDuSejour == 1) {
                            rabaisTotalPour1Jour = rabaisTotalPour1Jour.add(rabais);
                        } else if (dureeDuSejour == 2) {
                            rabaisTotalPour2Jour = rabaisTotalPour2Jour.add(rabais);
                        } else if (dureeDuSejour > 2) {
                            rabaisTotaPour2JourEtPlus = rabaisTotaPour2JourEtPlus.add(rabais);
                        }

                        // Calcul des sommes
                        montantAvantTaxesMoinsRabais = montantAvantTaxesEtRabais.subtract(rabais).setScale(2, RoundingMode.HALF_UP);
                        taxes = montantAvantTaxesMoinsRabais.multiply(NOUVELLE_TAXE).setScale(2, RoundingMode.HALF_UP);
                        totalDeTaxe = totalDeTaxe.add(taxes).setScale(2, RoundingMode.HALF_UP);
                        montantAvecTaxeSansRabais = montantAvantTaxesEtRabais.add(taxes).setScale(2, RoundingMode.HALF_UP);
                        montantTotalDesRabais = montantTotalDesRabais.add(rabais).setScale(2, RoundingMode.HALF_UP);
                        montantFinal = montantAvantTaxesMoinsRabais.add(taxes).setScale(2, RoundingMode.HALF_UP);
                        revenuTotalAvecTaxeSansRabais = revenuTotalAvecTaxeSansRabais.add(montantAvecTaxeSansRabais).setScale(2, RoundingMode.HALF_UP);
                        revenuTotalSansTaxesAvecRabais = revenuTotalSansTaxesAvecRabais.add(montantFinal).subtract(taxes).setScale(2, RoundingMode.HALF_UP);

                        // Affichage de la facture
                        System.out.println();
                        System.out.println("No Client: " + numeroDeClient);
                        System.out.println("Duree de l'activitee: " + dureeDuSejour + " jour(s)");
                        System.out.println("Nombre de participant(s): " + nombreDeParticipant);
                        System.out.println("Montant de la facture avant taxes et rabais: " + montantAvantTaxesEtRabais);
                        System.out.println("Taxes: " + taxes);
                        System.out.println("Montant avec taxe sans rabais: " + montantAvecTaxeSansRabais);
                        System.out.println("Rabais: " + rabais);
                        System.out.println("Montant final: " + montantFinal);
                        System.out.println();
                    }
                }
            }
        } while (numeroDeClient > LIMITE_INFERIEURE_POUR_TERMINAISON);

        if (nombreDeFacture > 0) {
            // Affichage des statistiques
            System.out.println();
            System.out.println("Nombre total de participant: " + nombreTotalDeParticipant);
            System.out.println("Nombre total de rabais de 15%: " + nbreDeRabais15PourCent);
            System.out.println("Nombre total de rabais de 10%: " + nbreDeRabais10PourCent);
            System.out.println("Nombre total de rabais de 5%: " + nbreDeRabais5PourCent);
            System.out.println("Nombre total de rabais de 0%: " + nbreDeRabais0PourCent);
            System.out.println("Montant total de rabais: " + montantTotalDesRabais);
            System.out.println("Revenu total avec taxe sans rabais: " + revenuTotalAvecTaxeSansRabais);
            System.out.println("total taxe : " + totalDeTaxe);
            System.out.println("Revenu total sans taxes avec rabais: " + revenuTotalSansTaxesAvecRabais);
            System.out.println("montant total des rabais 15%%: " + rabais15PourCent);
            System.out.println("montant total des rabais 10%%: " + rabais10PourCent);
            System.out.println("montant total des rabais 5%%: " + rabais5PourCent);
            System.out.println("montant total des rabais pour 1 jour: " + rabaisTotalPour1Jour);
            System.out.println("montant total des rabais pour 2 jours: " + rabaisTotalPour2Jour);
            System.out.println("montant total des rabais pour plus de 2 jours: " + rabaisTotaPour2JourEtPlus);
            System.out.println();
        }
        System.out.println("FIN NORMALE DU PROGRAMME");

    } // main
}
